package com.drotposta.unitils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *
 * @author elek
 */
public abstract class BaseInjector<T> implements Injector<T> {

    public boolean mustInjected(T bean, Class fieldClazz) {
        return true;
    }

    private void injectField(T bean, Field field, Class annotation) {
        if (mustInjected(bean, field.getType())) {
            try {
                field.set(bean, getValueToInject(bean, field, annotation));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void injectMethod(T bean, Method method) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    private void inject(T bean, Class currentClazz, Class annotation) {
        for (Method method : currentClazz.getMethods()) {
            if (method.isAnnotationPresent(annotation)) {
                injectMethod(bean, method);
            }
        }

        for (Field field : currentClazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(annotation)) {
                injectField(bean, field, annotation);
            }
        }

    }

    public void inject(T bean, Class annotation) {
        Class beanClazz = bean.getClass();
        inject(bean, beanClazz, annotation);

        Class parentClazz = beanClazz.getSuperclass();
        while (!parentClazz.equals(Object.class)) {
            inject(bean, parentClazz, annotation);
            parentClazz = parentClazz.getSuperclass();
        }
    }
}
